using System;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;
using org.tmatesoft.svn.core;
using org.tmatesoft.svn.core.wc;

namespace Subsync.Core.Subversion
{
	/// <summary>
	/// Author: Hoang Duc
	/// </summary>
	public class SVNCommit : CommandBase
	{
        /// <summary>
        /// We have our variables declared here.
        /// Access modifiers as you can observe, is public. Why?
        /// Because we trust our programmers.
        /// 
        /// Try to be verbose with the variable names.
        /// Also, try to include *sane defaults*. Take peg_revision for eg.
        /// </summary>
        private string working_path;
        //private SVNCommitPacket commitPacket;
        //private SVNCommitPacket[] commitPackets;
        private bool keepLocks = true;
        private bool keepChangelist;
        private string[] changelists;
        private bool force = false;
        private string commitMessage;
        private SVNProperties revisionProperties;
        private SVNDepth depth = SVNDepth.INFINITY;
        private java.io.File[] paths;
		
		/// <summary>
		/// Minimal Constructor
		/// </summary>
		/// <param name="working_path">
		/// A <see cref="System.String"/>
		/// </param>
		public SVNCommit(string working_path)
		{
            Debug.WriteLine("SVN Commit minimal Constructor with working_path");
            this.working_path = working_path;
            this.paths = new java.io.File[] { new java.io.File(working_path) };
		}        

        /// <summary>
        /// Files Array Constructor
        /// </summary>
        /// <param name="paths">
        /// A <see cref="java.io.File[]"/>
        /// </param>
        /// <param name="keepLocks">
        /// A <see cref="System.Boolean"/>
        /// </param>
        /// <param name="commitMessage">
        /// A <see cref="System.String"/>
        /// </param>
        /// <param name="revisionProperties">
        /// A <see cref="SVNProperties"/>
        /// </param>
        /// <param name="changelists">
        /// A <see cref="System.String[]"/>
        /// </param>
        /// <param name="keepChangelist">
        /// A <see cref="System.Boolean"/>
        /// </param>
        /// <param name="force">
        /// A <see cref="System.Boolean"/>
        /// </param>
        /// <param name="depth">
        /// A <see cref="SVNDepth"/>
        /// </param>
        public SVNCommit(java.io.File[] paths, bool keepLocks, string commitMessage, SVNProperties revisionProperties, 
            string[] changelists, bool keepChangelist, bool force, SVNDepth depth)
        {
            Debug.WriteLine("SVN Commit filePaths Constructor with Locks, ChangeList, RevProps, Depth and Message");
            this.paths = paths;
            this.keepLocks = keepLocks;
            this.commitMessage = commitMessage;
            this.revisionProperties = revisionProperties;
            this.changelists = changelists;
            this.keepChangelist = keepChangelist;
            this.force = force;
            this.depth = depth;
        }

        public override void Execute()
		{
            Debug.WriteLine("SVN Commit Execution");

            //library setup
            Tools.SetupLibrary();

            //load up the clients
            SVNClientManager cm = SVNClientManager.newInstance();
            SVNCommitClient cc = cm.getCommitClient();

            try
            {
                SVNCommitInfo commitInfo = cc.doCommit(this.paths, this.keepLocks, this.commitMessage, this.revisionProperties,
                    this.changelists, this.keepChangelist, this.force, this.depth);
                long newRev = commitInfo.getNewRevision();
                if (newRev == -1)
                    Debug.WriteLine("No new changes detected. No commit occurred.");
                else
                    Debug.WriteLine("Commited to new Revision " + newRev);
            }
            catch (SVNException e)
            {
                //we convert this exception to a non SVNKit exception.
                //we want to minimize interfacing with SVNkit outside of this namespace (abstraction)
                throw new SVNExecuteException(e.getMessage());
            }
		}
	}
}
